|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 /****************************************************************************** 00002 * 00003 * Freescale Semiconductor Inc. 00004 * (c) Copyright 2004-2011 Freescale Semiconductor 00005 * ALL RIGHTS RESERVED. 00006 * 00007 ****************************************************************************/ 00019 #include "freemaster.h" 00020 #include "freemaster_private.h" 00021 #include "freemaster_protocol.h" 00022 00023 #if FMSTR_USE_SERIAL 00024 00025 /*********************************** 00026 * local variables 00027 ***********************************/ 00028 00029 /* FreeMASTER communication buffer (in/out) plus the STS and LEN bytes */ 00030 static FMSTR_BCHR pcm_pCommBuffer[FMSTR_COMM_BUFFER_SIZE+3]; 00031 00032 /* FreeMASTER runtime flags */ 00033 /*lint -e{960} using union */ 00034 typedef volatile union 00035 { 00036 FMSTR_FLAGS all; 00037 00038 struct 00039 { 00040 unsigned bTxActive : 1; /* response is being transmitted */ 00041 #if FMSTR_USE_SCI 00042 unsigned bTxWaitTC : 1; /* response sent, wait for transmission complete */ 00043 #endif 00044 unsigned bTxLastCharSOB : 1; /* last transmitted char was equal to SOB */ 00045 unsigned bRxLastCharSOB : 1; /* last received character was SOB */ 00046 unsigned bRxMsgLengthNext : 1; /* expect the length byte next time */ 00047 #if FMSTR_USE_JTAG 00048 unsigned bJtagRIEPending : 1; /* JTAG RIE bit failed to be set, try again later */ 00049 #endif 00050 #if FMSTR_USE_USB_CDC || FMSTR_USE_MQX_IO || FMSTR_USE_JTAG 00051 unsigned bTxFirstSobSend : 1; /* to send SOB char at the begin of the packet */ 00052 #endif 00053 #if FMSTR_USE_MQX_IO 00054 unsigned bMqxReadyToSend : 1; /* to send next character in transmit routine */ 00055 #endif 00056 #if FMSTR_USE_USB_CDC 00057 unsigned bUsbCdcStartApp : 1; /* FreeMASTER USB CDC Application start Init Flag */ 00058 unsigned bUsbCdcStartTrans : 1; /* FreeMASTER USB CDC Application Carrier Activate Flag */ 00059 unsigned bUsbReadyToDecode : 1; /* FreeMASTER packet is received, ready to decode in Poll function in Short Interrupt mode */ 00060 #endif 00061 } flg; 00062 00063 } FMSTR_SERIAL_FLAGS; 00064 00065 static FMSTR_SERIAL_FLAGS pcm_wFlags; 00066 00067 /* receive and transmit buffers and counters */ 00068 static FMSTR_SIZE8 pcm_nTxTodo; /* transmission to-do counter (0 when tx is idle) */ 00069 static FMSTR_SIZE8 pcm_nRxTodo; /* reception to-do counter (0 when rx is idle) */ 00070 static FMSTR_BPTR pcm_pTxBuff; /* pointer to next byte to transmit */ 00071 static FMSTR_BPTR pcm_pRxBuff; /* pointer to next free place in RX buffer */ 00072 static FMSTR_BCHR pcm_nRxCheckSum; /* checksum of data being received */ 00073 00074 /*********************************** 00075 * local function prototypes 00076 ***********************************/ 00077 00078 static void FMSTR_Listen(void); 00079 static void FMSTR_SendError(FMSTR_BCHR nErrCode); 00080 00081 #else /* FMSTR_USE_SERIAL */ 00082 00083 /*lint -efile(766, freemaster_protocol.h) include file is not used in this case */ 00084 00085 #endif /* FMSTR_USE_SERIAL */ 00086 00087 #if FMSTR_USE_SCI || FMSTR_USE_JTAG 00088 /*********************************** 00089 * local variables 00090 ***********************************/ 00091 00092 /* SHORT_INTR receive queue (circular buffer) */ 00093 #if FMSTR_SHORT_INTR 00094 static FMSTR_BCHR pcm_pRQueueBuffer[FMSTR_COMM_RQUEUE_SIZE]; 00095 static FMSTR_BPTR pcm_pRQueueRP; /* SHORT_INTR queue read-pointer */ 00096 static FMSTR_BPTR pcm_pRQueueWP; /* SHORT_INTR queue write-pointer */ 00097 #endif 00098 00099 /*********************************** 00100 * local function prototypes 00101 ***********************************/ 00102 00103 #if FMSTR_SHORT_INTR 00104 static void FMSTR_RxQueue(FMSTR_BCHR nRxChar); 00105 static void FMSTR_RxDequeue(void); 00106 #endif 00107 00108 /*lint -esym(752,FMSTR_RxQueue) this may be unreferenced in some cases */ 00109 /*lint -esym(752,FMSTR_RxDequeue) this may be unreferenced in some cases */ 00110 00111 /******************************************************************************* 00112 * 00113 * @brief Routine to quick-receive a character (put to a queue only) 00114 * 00115 * This function puts received character into a queue and exits as soon as possible. 00116 * 00117 *******************************************************************************/ 00118 00119 #if FMSTR_SHORT_INTR 00120 00121 static void FMSTR_RxQueue(FMSTR_BCHR nRxChar) 00122 { 00123 /* future value of write pointer */ 00124 FMSTR_BPTR wpnext = pcm_pRQueueWP + 1; 00125 00126 /*lint -e{946} pointer arithmetic is okay here (same array) */ 00127 if(wpnext >= (pcm_pRQueueBuffer + FMSTR_COMM_RQUEUE_SIZE)) 00128 { 00129 wpnext = pcm_pRQueueBuffer; 00130 } 00131 00132 /* any space in queue? */ 00133 if(wpnext != pcm_pRQueueRP) 00134 { 00135 *pcm_pRQueueWP = (FMSTR_U8) nRxChar; 00136 pcm_pRQueueWP = wpnext; 00137 } 00138 } 00139 00140 #endif /* FMSTR_SHORT_INTR */ 00141 00142 /******************************************************************************* 00143 * 00144 * @brief Late processing of queued characters 00145 * 00146 * This function takes the queued characters and calls FMSTR_Rx() for each of them, 00147 * just like as the characters would be received from SCI one by one. 00148 * 00149 *******************************************************************************/ 00150 00151 #if FMSTR_SHORT_INTR 00152 00153 static void FMSTR_RxDequeue(void) 00154 { 00155 FMSTR_BCHR nChar = 0U; 00156 00157 /* get all queued characters */ 00158 while(pcm_pRQueueRP != pcm_pRQueueWP) 00159 { 00160 nChar = *pcm_pRQueueRP++; 00161 00162 /*lint -e{946} pointer arithmetic is okay here (same array) */ 00163 if(pcm_pRQueueRP >= (pcm_pRQueueBuffer + FMSTR_COMM_RQUEUE_SIZE)) 00164 { 00165 pcm_pRQueueRP = pcm_pRQueueBuffer; 00166 } 00167 00168 /* emulate the SCI receive event */ 00169 if(!pcm_wFlags.flg.bTxActive) 00170 { 00171 (void)FMSTR_Rx(nChar); 00172 } 00173 } 00174 } 00175 00176 #endif /* FMSTR_SHORT_INTR */ 00177 00178 #endif /* FMSTR_USE_SCI || FMSTR_USE_JTAG */ 00179 00180 #if FMSTR_USE_SCI 00181 00182 /**************************************************************************/ 00192 void FMSTR_ProcessSCI(void) 00193 { 00194 /* read & clear status */ 00195 FMSTR_SCISR wSciSR = FMSTR_SCI_RDCLRSR(); 00196 00197 /* transmitter active and empty? */ 00198 if (pcm_wFlags.flg.bTxActive) 00199 { 00200 /* able to accept another character? */ 00201 if(wSciSR & FMSTR_SCISR_TDRE) 00202 { 00203 FMSTR_U8 ch; 00204 //(void)FMSTR_Tx(&ch); 00205 /* just put the byte into the SCI transmit buffer */ 00206 if(!FMSTR_Tx(&ch)) 00207 FMSTR_SCI_PUTCHAR((FMSTR_U8) ch); 00208 } 00209 00210 #if FMSTR_SCI_HAS_TXQUEUE 00211 /* waiting for transmission complete flag? */ 00212 if(pcm_wFlags.flg.bTxWaitTC && (wSciSR & FMSTR_SCISR_TC)) 00213 { 00214 /* after TC, we can switch to listen mode safely */ 00215 FMSTR_Listen(); 00216 } 00217 #endif 00218 00219 00220 #if !FMSTR_SCI_TWOWIRE_ONLY 00221 /* read-out and ignore any received character (loopback) */ 00222 if(wSciSR & FMSTR_SCISR_RDRF) 00223 { 00224 /*lint -esym(550, nRxChar) */ 00225 volatile FMSTR_U16 nRxChar; 00226 nRxChar = FMSTR_SCI_GETCHAR(); 00227 } 00228 #endif 00229 } 00230 /* transmitter not active, able to receive */ 00231 else 00232 { 00233 /* data byte received? */ 00234 if (wSciSR & FMSTR_SCISR_RDRF) 00235 { 00236 FMSTR_BCHR nRxChar = 0U; 00237 nRxChar = (FMSTR_BCHR) FMSTR_SCI_GETCHAR(); 00238 00239 #if FMSTR_SHORT_INTR 00240 FMSTR_RxQueue(nRxChar); 00241 #else 00242 (void)FMSTR_Rx(nRxChar); 00243 #endif 00244 } 00245 } 00246 } 00247 00248 #endif /* FMSTR_USE_SCI */ 00249 00250 00251 #if FMSTR_USE_JTAG 00252 00253 /*********************************** 00254 * local function prototypes 00255 ***********************************/ 00256 00257 static void FMSTR_FlushJtagTx(void); 00258 00259 /**************************************************************************/ 00268 static void FMSTR_FlushJtagTx(void) 00269 { 00270 FMSTR_U8 i; 00271 FMSTR_U32 wJtagTxData; 00272 register FMSTR_U16 wJtagSR = FMSTR_JTAG_GETSR(); 00273 /* complete word to send */ 00274 for (i=0; i<4; i++) 00275 { 00276 FMSTR_U8 ch; 00277 if (FMSTR_Tx(&ch)) 00278 ch = 0xff; 00279 wJtagTxData = (wJtagTxData << 8) | ch; 00280 } 00281 00282 /* send the word just completed */ 00283 FMSTR_JTAG_PUTDWORD(wJtagTxData); 00284 } 00285 00286 /**************************************************************************/ 00296 void FMSTR_ProcessJTAG(void) 00297 { 00298 /* read & clear status */ 00299 register FMSTR_U16 wJtagSR = FMSTR_JTAG_GETSR(); 00300 00301 /* transmitter active? */ 00302 if (pcm_wFlags.flg.bTxActive) 00303 { 00304 /* able to transmit a new character? (TX must be empty = read-out by PC) */ 00305 if(!(wJtagSR & FMSTR_JTAG_OTXRXSR_TDF)) 00306 { 00307 00308 #if FMSTR_USE_JTAG_TXFIX 00309 /* if TDF bit is useless due to silicon bug, use the RX flag */ 00310 /* instead (PC sends us a dummy word to kick the RX flag on) */ 00311 if(wJtagSR & FMSTR_JTAG_OTXRXSR_RDF) 00312 #endif 00313 { 00314 FMSTR_FlushJtagTx(); 00315 } 00316 } 00317 00318 /* ignore (read-out) the JTAG-received word */ 00319 if(wJtagSR & FMSTR_JTAG_OTXRXSR_RDF) 00320 { 00321 /*lint -esym(550, nRxWord) */ 00322 volatile FMSTR_U16 nRxWord; 00323 nRxWord = FMSTR_JTAG_GETWORD(); 00324 } 00325 } 00326 /* transmitter not active */ 00327 else 00328 { 00329 /* JTAG 32bit word (four bytes) received? */ 00330 if(wJtagSR & FMSTR_JTAG_OTXRXSR_RDF) 00331 { 00332 register FMSTR_U32 nRxDWord; 00333 FMSTR_INDEX i; 00334 00335 nRxDWord = FMSTR_JTAG_GETDWORD(); 00336 00337 /* process all bytes, MSB first */ 00338 for(i=0; i<4; i++) 00339 { 00340 #if FMSTR_SHORT_INTR 00341 FMSTR_RxQueue((FMSTR_BCHR)((nRxDWord >> 24U) & 0xffU)); 00342 00343 #else 00344 (void)FMSTR_Rx((FMSTR_BCHR)((nRxDWord >> 24U) & 0xffU)); 00345 00346 /* ignore the rest if previous bytes triggered a transmission */ 00347 /* (i.e. the packet was complete and only filled-up to 32bit word) */ 00348 if(pcm_wFlags.flg.bTxActive) 00349 { 00350 break; 00351 } 00352 #endif 00353 /* next byte of 32bit word */ 00354 nRxDWord = nRxDWord << 8; 00355 } 00356 } 00357 } 00358 } 00359 00360 #endif /* FMSTR_USE_JTAG */ 00361 00362 /****************************************************************************** 00363 ****************************************************************************/ 00369 #if FMSTR_USE_MQX_IO 00370 00371 #include <mqx.h> 00372 #include <bsp.h> 00373 00374 /*********************************** 00375 * local variables 00376 ***********************************/ 00377 00378 static FILE_PTR devfd = NULL; /* pointer to open FreeMASTER communication interface */ 00379 00380 /*********************************** 00381 * local function prototypes 00382 ***********************************/ 00383 00384 static FMSTR_BOOL FMSTR_InitMQX(void); 00385 static void FMSTR_ProcessMQXIO(void); 00386 00387 /**************************************************************************/ 00393 static FMSTR_BOOL FMSTR_InitMQX(void) 00394 { 00395 /* Open communication port */ 00396 devfd = fopen (FMSTR_MQX_IO_CHANNEL, (pointer) FMSTR_MQX_IO_PARAMETER); 00397 00398 return (devfd != NULL); 00399 } 00400 00401 /******************************************************************************* 00402 * 00403 * @brief Handle MQX IO serial communication (both TX and RX) 00404 * 00405 * This function calls MQX IO fread() function to get character and process it by 00406 * 00407 * FMSTR_Rx function when FreeMASTER packet is receiving. This function also transmit 00408 * 00409 * FreeMASTER response. Character to be send is provided by call of FMSTR_Tx function 00410 * 00411 * and passed down to fwrite() function. 00412 * 00413 *******************************************************************************/ 00414 00415 static void FMSTR_ProcessMQXIO(void) 00416 { 00417 if (devfd != NULL) 00418 { 00419 static FMSTR_U8 TxChar = 0; 00420 /* transmitter not active, able to receive */ 00421 if ((!pcm_wFlags.flg.bTxActive) && (!pcm_wFlags.flg.bMqxReadyToSend)) 00422 { 00423 FMSTR_U8 nRxChar; 00424 /* read all available bytes from communication interface */ 00425 while (fread(&nRxChar, 1, 1, devfd)) { 00426 if(FMSTR_Rx(nRxChar)) 00427 break; 00428 } 00429 } 00430 00431 /* transmitter active and empty? */ 00432 if (pcm_wFlags.flg.bTxActive || pcm_wFlags.flg.bMqxReadyToSend) 00433 { 00434 while (1) 00435 { 00436 /* write character when is valid */ 00437 if (pcm_wFlags.flg.bMqxReadyToSend) 00438 { 00439 if (fwrite(&TxChar, 1, 1, devfd)) 00440 /* character was successfully send, ready to get next character */ 00441 pcm_wFlags.flg.bMqxReadyToSend = 0; 00442 else 00443 /* character write failed, needs to be send next call */ 00444 break; 00445 00446 } 00447 /* is ready to get next character? */ 00448 if (FMSTR_Tx((FMSTR_U8*)&TxChar)) 00449 /* FreeMASTER packet is sent, exit loop */ 00450 break; 00451 /* read next character, set its validity to be send */ 00452 pcm_wFlags.flg.bMqxReadyToSend = 1; 00453 } 00454 } 00455 } 00456 } 00457 00458 #else /* FMSTR_USE_MQX_IO */ 00459 00460 /*lint -efile(766, freemaster_protocol.h) include file is not used in this case */ 00461 00462 #endif /* FMSTR_USE_MQX_IO */ 00463 00464 /****************************************************************************** 00465 ****************************************************************************/ 00471 #if FMSTR_USE_USB_CDC 00472 #include "usb_cdc.h" /* USB CDC Class Header File */ 00473 00474 /*********************************** 00475 * Global variables 00476 ***********************************/ 00477 FMSTR_U8 send_buf[DIC_BULK_IN_ENDP_PACKET_SIZE]; //buffer for store packet to send 00478 00479 /*********************************** 00480 * local function prototypes 00481 ***********************************/ 00482 00483 static FMSTR_BOOL FMSTR_InitUSB(void); 00484 static void FMSTR_ProcessUSB(void); 00485 static void FMSTR_SendUsbPacket(void); 00486 00487 static void FMSTR_USB_CDC_Callback(FMSTR_U8 controller_ID, 00488 FMSTR_U8 event_type, void* val); 00489 static void FMSTR_USB_CDC_Notify_Callback(FMSTR_U8 controller_ID, 00490 FMSTR_U8 event_type, void* val); 00491 00492 /**************************************************************************/ 00498 static FMSTR_BOOL FMSTR_InitUSB(void) 00499 { 00500 FMSTR_U8 error; 00501 00502 /* Initialize the USB interface */ 00503 error = USB_Class_CDC_Init(FMSTR_USB_CDC_ID,FMSTR_USB_CDC_Callback, 00504 NULL,FMSTR_USB_CDC_Notify_Callback); 00505 if(error != USB_OK) 00506 { 00507 /* Error initializing USB-CDC Class */ 00508 return FMSTR_FALSE; 00509 } 00510 00511 return FMSTR_TRUE; 00512 } 00513 00514 /**************************************************************************/ 00522 static void FMSTR_ProcessUSB(void) 00523 { 00524 /* call the periodic task function */ 00525 USB_Class_CDC_Periodic_Task(); 00526 00527 #if FMSTR_SHORT_INTR 00528 /*check whether enumeration is complete or not */ 00529 if((pcm_wFlags.flg.bUsbCdcStartApp) && (pcm_wFlags.flg.bUsbCdcStartTrans)) 00530 { 00531 /*transmitter not active, able to receive */ 00532 if ((!pcm_wFlags.flg.bTxActive) && (pcm_wFlags.flg.bUsbReadyToDecode)) 00533 { 00534 FMSTR_ProtocolDecoder(pcm_pCommBuffer); 00535 pcm_wFlags.flg.bUsbReadyToDecode = 0; 00536 } 00537 } 00538 #endif 00539 } 00540 00541 00542 /**************************************************************************/ 00552 static void FMSTR_SendUsbPacket(void) 00553 { 00554 /* transmitter active and empty? */ 00555 if (pcm_wFlags.flg.bTxActive) 00556 { 00557 FMSTR_U8 index; 00558 00559 /* fill in the transmitter buffer */ 00560 for (index = 0; index < DIC_BULK_IN_ENDP_PACKET_SIZE; index++){ 00561 FMSTR_U8 TxChar; 00562 if (FMSTR_Tx(&TxChar)) 00563 break; 00564 send_buf[index] = TxChar; 00565 } 00566 00567 USB_Class_CDC_Interface_DIC_Send_Data(FMSTR_USB_CDC_ID, send_buf,index); 00568 } 00569 } 00570 00571 /****************************************************************************** 00572 * 00573 * @name FMSTR_USB_CDC_Callback 00574 * 00575 * @brief This function handles Class callback 00576 * 00577 * @param controller_ID : Controller ID 00578 * @param event_type : Value of the event 00579 * @param val : gives the configuration value 00580 * 00581 * @return None 00582 * 00583 ***************************************************************************** 00584 * This function is called from the class layer whenever reset occurs or enum 00585 * is complete. After the enum is complete this function sets a variable so 00586 * that the application can start. 00587 * This function also receives DATA Send and RECEIVED Events 00588 *****************************************************************************/ 00589 00590 static void FMSTR_USB_CDC_Callback ( 00591 FMSTR_U8 controller_ID, /* [IN] Controller ID */ 00592 FMSTR_U8 event_type, /* [IN] value of the event */ 00593 void* val /* [IN] gives the configuration value */ 00594 ) 00595 { 00596 UNUSED (controller_ID) 00597 UNUSED (val) 00598 if(event_type == USB_APP_BUS_RESET) 00599 { 00600 pcm_wFlags.flg.bUsbCdcStartApp = 0U; 00601 } 00602 else if(event_type == USB_APP_ENUM_COMPLETE) 00603 { 00604 pcm_wFlags.flg.bUsbCdcStartApp = 1U; 00605 } 00606 else if((event_type == USB_APP_DATA_RECEIVED) && (pcm_wFlags.flg.bUsbCdcStartTrans)) 00607 { 00608 /* manage received data */ 00609 if (pcm_wFlags.flg.bUsbCdcStartApp) 00610 { 00611 /* Copy Received Data buffer to Application Buffer */ 00612 USB_PACKET_SIZE BytesToBeCopied; 00613 APP_DATA_STRUCT* dp_rcv = (APP_DATA_STRUCT*)val; 00614 BytesToBeCopied = dp_rcv->data_size; 00615 00616 /* transmitter not active, able to receive */ 00617 if (!pcm_wFlags.flg.bTxActive) 00618 { 00619 FMSTR_U8 index; 00620 for(index = 0 ; index<BytesToBeCopied ; index++){ 00621 if(FMSTR_Rx(dp_rcv->data_ptr[index])){ 00622 break; 00623 } 00624 } 00625 /* continue receiving, when packet is not decoded */ 00626 if (index == BytesToBeCopied) /* receive next packet only when are not received all bytes of packet */ 00627 (void)USB_Class_CDC_Interface_DIC_Recv_Data(FMSTR_USB_CDC_ID, NULL, 0); 00628 } 00629 } 00630 } 00631 else if((event_type == USB_APP_SEND_COMPLETE) && (pcm_wFlags.flg.bUsbCdcStartTrans)) 00632 { 00633 if ((pcm_wFlags.flg.bUsbCdcStartApp) && (pcm_wFlags.flg.bTxActive)) 00634 /* Finalize USB packet to transmit and send packet */ 00635 FMSTR_SendUsbPacket(); 00636 else 00637 /* Previous Send is complete. Queue next receive */ 00638 (void)USB_Class_CDC_Interface_DIC_Recv_Data(FMSTR_USB_CDC_ID, NULL, 0); 00639 } 00640 00641 return; 00642 } 00643 00644 /****************************************************************************** 00645 * 00646 * @name FMSTR_USB_CDC_Notify_Callback 00647 * 00648 * @brief This function handles PSTN Sub Class callbacks 00649 * 00650 * @param controller_ID : Controller ID 00651 * @param event_type : PSTN Event Type 00652 * @param val : gives the configuration value 00653 * 00654 * @return None 00655 * 00656 ***************************************************************************** 00657 * This function handles USB_APP_CDC_CARRIER_ACTIVATED and 00658 * USB_APP_CDC_CARRIER_DEACTIVATED PSTN Events 00659 *****************************************************************************/ 00660 00661 static void FMSTR_USB_CDC_Notify_Callback ( 00662 FMSTR_U8 controller_ID, /* [IN] Controller ID */ 00663 FMSTR_U8 event_type, /* [IN] PSTN Event Type */ 00664 void* val /* [IN] gives the configuration value */ 00665 ) 00666 { 00667 UNUSED (controller_ID) 00668 UNUSED (val) 00669 if(pcm_wFlags.flg.bUsbCdcStartApp) 00670 { 00671 if(event_type == USB_APP_CDC_CARRIER_ACTIVATED) 00672 { 00673 pcm_wFlags.flg.bUsbCdcStartTrans = 1U; 00674 } 00675 else if(event_type == USB_APP_CDC_CARRIER_DEACTIVATED) 00676 { 00677 pcm_wFlags.flg.bUsbCdcStartTrans = 0U; 00678 } 00679 } 00680 return; 00681 } 00682 00683 #else /* FMSTR_USE_USB_CDC */ 00684 00685 /*lint -efile(766, freemaster_protocol.h) include file is not used in this case */ 00686 00687 #endif /* FMSTR_USE_USB_CDC */ 00688 00689 00690 #if FMSTR_USE_SERIAL 00691 00692 /**************************************************************************/ 00700 static void FMSTR_Listen(void) 00701 { 00702 pcm_nRxTodo = 0U; 00703 00704 /* disable transmitter state machine */ 00705 pcm_wFlags.flg.bTxActive = 0U; 00706 00707 #if FMSTR_USE_SCI 00708 pcm_wFlags.flg.bTxWaitTC = 0U; 00709 /* disable transmitter, enable receiver (enables single-wire connection) */ 00710 #if !FMSTR_SCI_TWOWIRE_ONLY 00711 FMSTR_SCI_TD(); 00712 FMSTR_SCI_RE(); 00713 #endif 00714 #endif /* FMSTR_USE_SCI */ 00715 00716 /* disable transmit, enable receive interrupts */ 00717 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR 00718 #if FMSTR_USE_SCI 00719 FMSTR_SCI_DTXI(); /* disable SCI transmit interrupt */ 00720 FMSTR_SCI_ERXI(); /* enable SCI receive interrupt */ 00721 00722 #elif FMSTR_USE_JTAG 00723 FMSTR_JTAG_DTXI(); /* disable JTAG transmit interrupt */ 00724 FMSTR_JTAG_ERXI(); /* enable JTAG receive interrupt */ 00725 00726 /* RIE bit is forced low by HW until EONCE is first accessed, we will try again in FMSTR_Poll */ 00727 if(!FMSTR_JTAG_ERXI_CHECK()) 00728 pcm_wFlags.flg.bJtagRIEPending = 1; 00729 00730 #endif /* FMSTR_USE_SCI / FMSTR_USE_JTAG */ 00731 #endif /* FMSTR_SHORT_INTR || FMSTR_LONG_INTR */ 00732 } 00733 00734 /**************************************************************************/ 00742 static void FMSTR_SendError(FMSTR_BCHR nErrCode) 00743 { 00744 /* fill & send single-byte response */ 00745 *pcm_pCommBuffer = nErrCode; 00746 FMSTR_SendResponse(pcm_pCommBuffer, 1U); 00747 } 00748 00749 /**************************************************************************/ 00761 void FMSTR_SendResponse(FMSTR_BPTR pResponse, FMSTR_SIZE8 nLength) 00762 { 00763 FMSTR_U16 chSum = 0U; 00764 FMSTR_U8 i, c; 00765 00766 /* remember the buffer to be sent */ 00767 pcm_pTxBuff = pResponse; 00768 00769 /* status byte and data are already there, compute checksum only */ 00770 for (i=0U; i<nLength; i++) 00771 { 00772 c = 0U; 00773 pResponse = FMSTR_ValueFromBuffer8(&c, pResponse); 00774 /* add character to checksum */ 00775 chSum += c; 00776 /* prevent saturation to happen on DSP platforms */ 00777 chSum &= 0xffU; 00778 } 00779 00780 /* store checksum after the message */ 00781 pResponse = FMSTR_ValueToBuffer8(pResponse, (FMSTR_U8) (((FMSTR_U16)~(chSum)) + 1U)); 00782 00783 /* send the message and the checksum and the SOB */ 00784 pcm_nTxTodo = (FMSTR_SIZE8) (nLength + 1U); 00785 00786 /* now transmitting the response */ 00787 pcm_wFlags.flg.bTxActive = 1U; 00788 00789 #if FMSTR_USE_USB_CDC || FMSTR_USE_MQX_IO || FMSTR_USE_JTAG 00790 pcm_wFlags.flg.bTxFirstSobSend = 1U; 00791 #endif 00792 00793 #if FMSTR_USE_SCI 00794 pcm_wFlags.flg.bTxWaitTC = 0U; 00795 #endif 00796 00797 /* do not replicate the initial SOB */ 00798 pcm_wFlags.flg.bTxLastCharSOB = 0U; 00799 00800 #if FMSTR_USE_SCI 00801 { 00802 /*lint -esym(550, dummySR) */ 00803 volatile FMSTR_SCISR dummySR; 00804 00805 /* disable receiver, enable transmitter (single-wire communication) */ 00806 #if !FMSTR_SCI_TWOWIRE_ONLY 00807 FMSTR_SCI_RD(); 00808 FMSTR_SCI_TE(); 00809 #endif 00810 /* kick on the SCI transmission (also clears TX Empty flag on some platforms) */ 00811 dummySR = FMSTR_SCI_GETSR(); 00812 FMSTR_SCI_PUTCHAR(FMSTR_SOB); 00813 } 00814 00815 #elif FMSTR_USE_JTAG 00816 /* kick on the JTAG transmission */ 00817 FMSTR_FlushJtagTx(); 00818 #endif 00819 00820 /* TX interrupt enable, RX interrupt disable */ 00821 #if FMSTR_LONG_INTR || FMSTR_SHORT_INTR 00822 #if FMSTR_USE_SCI 00823 FMSTR_SCI_DRXI(); 00824 FMSTR_SCI_ETXI(); 00825 00826 #elif FMSTR_USE_JTAG 00827 #if FMSTR_USE_JTAG_TXFIX 00828 /* in TX-bugfix mode, keep the RX interrupt enabled as it */ 00829 /* is used as "able-to-TX" notification from the PC */ 00830 FMSTR_JTAG_ERXI(); 00831 #else 00832 /* otherwise, JTAG is very same as the SCI */ 00833 if(pcm_wFlags.flg.bTxActive) //enable TX interrupt only when is not one word response 00834 { 00835 FMSTR_JTAG_DRXI(); 00836 FMSTR_JTAG_ETXI(); 00837 } 00838 #endif 00839 00840 #elif FMSTR_USE_USB_CDC 00841 if ((pcm_wFlags.flg.bUsbCdcStartApp) && (pcm_wFlags.flg.bTxActive) && (pcm_wFlags.flg.bUsbCdcStartTrans)) 00842 /* Finalize USB packet to transmit and send packet */ 00843 FMSTR_SendUsbPacket(); 00844 else 00845 /* Previous Send is complete. Queue next receive */ 00846 (void)USB_Class_CDC_Interface_DIC_Recv_Data(FMSTR_USB_CDC_ID, NULL, 0); 00847 #endif 00848 #endif /* FMSTR_LONG_INTR || FMSTR_SHORT_INTR */ 00849 } 00850 00851 /**************************************************************************/ 00861 FMSTR_BOOL FMSTR_Tx(FMSTR_U8* pTxChar) 00862 { 00863 #if FMSTR_USE_USB_CDC || FMSTR_USE_MQX_IO || FMSTR_USE_JTAG 00864 /* to send first SOB byte*/ 00865 if (pcm_wFlags.flg.bTxFirstSobSend) 00866 { 00867 *pTxChar = FMSTR_SOB; 00868 pcm_wFlags.flg.bTxFirstSobSend = 0U; 00869 return FMSTR_FALSE; 00870 } 00871 #endif 00872 if (pcm_nTxTodo) 00873 { 00874 /* fetch & send character ready to transmit */ 00875 /*lint -e{534} ignoring return value */ 00876 FMSTR_ValueFromBuffer8(pTxChar, pcm_pTxBuff); 00877 00878 /* first, handle the replicated SOB characters */ 00879 if (*pTxChar == FMSTR_SOB) 00880 { 00881 pcm_wFlags.flg.bTxLastCharSOB ^= 1U; 00882 if ((pcm_wFlags.flg.bTxLastCharSOB)) 00883 { 00884 /* yes, repeat the SOB next time */ 00885 return FMSTR_FALSE; 00886 } 00887 } 00888 /* no, advance tx buffer pointer */ 00889 pcm_nTxTodo--; 00890 pcm_pTxBuff = FMSTR_SkipInBuffer(pcm_pTxBuff, 1U); 00891 return FMSTR_FALSE; 00892 } 00893 00894 /* when SCI TX buffering is enabled, we must first wait until all 00895 characters are physically transmitted (before disabling transmitter) */ 00896 #if FMSTR_USE_SCI 00897 #if FMSTR_SCI_HAS_TXQUEUE 00898 pcm_wFlags.flg.bTxWaitTC = 1; 00899 00900 /* wait for SCI TC interrupt */ 00901 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR 00902 FMSTR_SCI_ETCI(); 00903 #endif 00904 #else 00905 /* start listening immediately */ 00906 FMSTR_Listen(); 00907 #endif 00908 #else 00909 /* start listening immediately */ 00910 FMSTR_Listen(); 00911 #endif 00912 00913 return FMSTR_TRUE; 00914 } 00915 00916 00917 /**************************************************************************/ 00928 FMSTR_BOOL FMSTR_Rx(FMSTR_BCHR nRxChar) 00929 { 00930 FMSTR_SERIAL_FLAGS * pflg = &pcm_wFlags; 00931 /* first, handle the replicated SOB characters */ 00932 if(nRxChar == FMSTR_SOB) 00933 { 00934 pflg->flg.bRxLastCharSOB ^= 1; 00935 if(pflg->flg.bRxLastCharSOB) 00936 { 00937 /* this is either the first byte of replicated SOB or a */ 00938 /* real Start-of-Block mark - we will decide next time in FMSTR_Rx */ 00939 return FMSTR_FALSE; 00940 } 00941 } 00942 00943 /* we have got a common character preceded by the SOB - */ 00944 /* this is the command code! */ 00945 if(pflg->flg.bRxLastCharSOB) 00946 { 00947 /* reset receiving process */ 00948 pcm_pRxBuff = pcm_pCommBuffer; 00949 *pcm_pRxBuff++ = nRxChar; 00950 00951 /* start computing the checksum */ 00952 pcm_nRxCheckSum = nRxChar; 00953 pcm_nRxTodo = 0U; 00954 00955 /* if the standard command was received, the message length will come in next byte */ 00956 pflg->flg.bRxMsgLengthNext = 1U; 00957 00958 /* fast command? */ 00959 if(!((~nRxChar) & FMSTR_FASTCMD)) 00960 { 00961 /* fast command received, there will be no length information */ 00962 pflg->flg.bRxMsgLengthNext = 0U; 00963 /* as it is encoded in the command byte directly */ 00964 pcm_nRxTodo = (FMSTR_SIZE8) 00965 (((((FMSTR_SIZE8)nRxChar) & FMSTR_FASTCMD_DATALEN_MASK) >> FMSTR_FASTCMD_DATALEN_SHIFT) + 1U); 00966 } 00967 00968 /* command code stored & processed */ 00969 pflg->flg.bRxLastCharSOB = 0U; 00970 return FMSTR_FALSE; 00971 } 00972 00973 /* we are waiting for the length byte */ 00974 if(pflg->flg.bRxMsgLengthNext) 00975 { 00976 /* this byte, total data length and the checksum */ 00977 pcm_nRxTodo = (FMSTR_SIZE8) (1U + ((FMSTR_SIZE8)nRxChar) + 1U); 00978 /* now read the data bytes */ 00979 pflg->flg.bRxMsgLengthNext = 0U; 00980 00981 } 00982 00983 /* waiting for a data byte? */ 00984 if(pcm_nRxTodo) 00985 { 00986 /* add this byte to checksum */ 00987 pcm_nRxCheckSum += nRxChar; 00988 00989 /* decrease number of expected bytes */ 00990 pcm_nRxTodo--; 00991 /* was it the last byte of the message (checksum)? */ 00992 if(!pcm_nRxTodo) 00993 { 00994 /* receive buffer overflow? */ 00995 if(pcm_pRxBuff == NULL) 00996 { 00997 FMSTR_SendError(FMSTR_STC_CMDTOOLONG); 00998 } 00999 /* checksum error? */ 01000 else if((pcm_nRxCheckSum & 0xffU) != 0U) 01001 { 01002 FMSTR_SendError(FMSTR_STC_CMDCSERR); 01003 } 01004 /* message is okay */ 01005 else 01006 { 01007 #if FMSTR_USE_USB_CDC && FMSTR_SHORT_INTR 01008 /* Decode protocol and send response in Poll function */ 01009 pflg->flg.bUsbReadyToDecode = 1U; 01010 #else 01011 /* do decode now! */ 01012 FMSTR_ProtocolDecoder(pcm_pCommBuffer); 01013 #endif 01014 } 01015 01016 return FMSTR_TRUE; 01017 } 01018 /* not the last character yet */ 01019 else 01020 { 01021 /* is there still a space in the buffer? */ 01022 if(pcm_pRxBuff) 01023 { 01024 /*lint -e{946} pointer arithmetic is okay here (same array) */ 01025 if(pcm_pRxBuff < (pcm_pCommBuffer + FMSTR_COMM_BUFFER_SIZE)) 01026 { 01027 /* store byte */ 01028 *pcm_pRxBuff++ = nRxChar; 01029 } 01030 /* buffer is full! */ 01031 else 01032 { 01033 /* NULL rx pointer means buffer overflow - but we still need */ 01034 /* to receive all message characters (for the single-wire mode) */ 01035 /* so keep "receiving" - but throw away all characters from now */ 01036 pcm_pRxBuff = NULL; 01037 } 01038 } 01039 } 01040 } 01041 return FMSTR_FALSE; 01042 } 01043 01044 /**************************************************************************/ 01050 FMSTR_BOOL FMSTR_InitSerial(void) 01051 { 01052 /* initialize all state variables */ 01053 pcm_wFlags.all = 0U; 01054 pcm_nTxTodo = 0U; 01055 01056 /* Initialize SCI and JTAG interface */ 01057 #if FMSTR_USE_SCI && FMSTR_SCI_TWOWIRE_ONLY 01058 /* to enable TX and RX together in FreeMASTER initialization */ 01059 FMSTR_SCI_TE_RE(); 01060 #endif 01061 01062 #if FMSTR_SHORT_INTR & (FMSTR_USE_SCI || FMSTR_USE_JTAG) 01063 pcm_pRQueueRP = pcm_pRQueueBuffer; 01064 pcm_pRQueueWP = pcm_pRQueueBuffer; 01065 #endif 01066 01067 #if FMSTR_USE_MQX_IO 01068 if (!FMSTR_InitMQX()) 01069 return FMSTR_FALSE; 01070 #endif 01071 01072 #if FMSTR_USE_USB_CDC 01073 if (!FMSTR_InitUSB()) 01074 return FMSTR_FALSE; 01075 #endif 01076 01077 /* start listening for commands */ 01078 FMSTR_Listen(); 01079 return FMSTR_TRUE; 01080 } 01081 01082 01083 /******************************************************************************* 01084 * 01085 * @brief API: Main "Polling" call from the application main loop 01086 * 01087 * This function either handles all the SCI communication (polling-only mode = 01088 * FMSTR_POLL_DRIVEN) or decodes messages received on the background by SCI interrupt 01089 * (short-interrupt mode = FMSTR_SHORT_INTR). 01090 * 01091 * In the JTAG interrupt-driven mode (both short and long), this function also checks 01092 * if setting the JTAG RIE bit failed recently. This may happen because of the 01093 * RIE is held low by the EONCE hardware until the EONCE is first accessed from host. 01094 * FMSTR_Init (->FMSTR_Listen) is often called while the PC-side FreeMASTER is still 01095 * turned off. So really, the JTAG is not enabled by this time and RIE bit is not set. 01096 * This problem is detected (see how bJtagRIEPending is set above in FSMTR_Listen) 01097 * and it is tried to be fixed periodically here in FMSTR_Poll. 01098 * 01099 *******************************************************************************/ 01100 01101 void FMSTR_Poll(void) 01102 { 01103 #if !FMSTR_POLL_DRIVEN && FMSTR_USE_JTAG 01104 /* in the interrupt-driven JTAG mode, the JTAG RIE may have failed to be set recently */ 01105 if(pcm_wFlags.flg.bJtagRIEPending) 01106 { 01107 FMSTR_JTAG_ERXI(); /* try to enable JTAG receive interrupt now */ 01108 01109 /* succeeded? */ 01110 if(FMSTR_JTAG_ERXI_CHECK()) 01111 pcm_wFlags.flg.bJtagRIEPending = 0; /* yes!, enough until it fails again (never?) */ 01112 } 01113 #endif 01114 01115 #if FMSTR_USE_MQX_IO 01116 /* polled MQX IO mode */ 01117 FMSTR_ProcessMQXIO(); 01118 #endif 01119 01120 #if FMSTR_POLL_DRIVEN 01121 01122 #if FMSTR_USE_SCI 01123 /* polled SCI mode */ 01124 FMSTR_ProcessSCI(); 01125 01126 #elif FMSTR_USE_JTAG 01127 /* polled JTAG mode */ 01128 FMSTR_ProcessJTAG(); 01129 #endif 01130 01131 #elif FMSTR_SHORT_INTR 01132 01133 #if FMSTR_USE_USB_CDC 01134 /* */ 01135 FMSTR_ProcessUSB(); 01136 #elif (FMSTR_USE_SCI || FMSTR_USE_JTAG) 01137 01138 /* process queued SCI characters */ 01139 FMSTR_RxDequeue(); 01140 #endif 01141 01142 #endif 01143 } 01144 01145 #endif